home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 145
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin
/
tools
/
sharp
/
sxwork3.lzh
/
サンプル実用編
/
ペイント
/
GPSUB.C
< prev
next >
Wrap
Text File
|
1994-03-10
|
33KB
|
964 lines
/******************************************************************************
* gpsub.c: グラフペイントのサブ関数
******************************************************************************
* Workroom SX-68K Sample Program Copyright 1994 SHARP
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sxmemory.h> /* メモリマンを利用するときに必要 */
#include <console.h> /* コンソール系マネージャを利用するときに必要 */
#include <event.h> /* イベントマンを利用するときに必要 */
#include <sxgraph.h> /* グラフ系マネージャを利用するときに必要 */
#include <window.h> /* ウィンドウマンを利用するときに必要 */
#include <control.h> /* コントロールマンを利用するときに必要 */
#include <dialog.h> /* ダイアログマンを利用するときに必要 */
#include <text.h> /* テキストマンを利用するときに必要 */
#include <task.h> /* タスクマンを利用するときに必要 */
#include "gpaint.h" /* このプログラム固有のヘッダファイル */
/* ファイルネーム入出力用疑似ダイアログレクタングル */
Rect rcFdlg = { 10, 10, 334, 118 };
/* ファイル入出力用疑似ダイアログのビューレクタングル */
Rect rcView = { 28, 42, 316, 68 };
Rect brrect = { 0, 0, 16, 16 }; /* ブラシ用レクタングル */
static Rect rcCbtnJ = { 239, 84, 269, 103 };
static Rect rcCbtnT = { 279, 84, 309, 103 };
/******************************************************************************
* createOffScreen(): オフスクリーンの作成
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* 戻り値: BOOLEAN = TRUE: 初期化成功
* = FALSE: 初期化失敗
*/
BOOLEAN createOffScreen(ComVal *pcv)
{
int i;
int fileexist;
FILE *hFile = NULL;
Graph fgraph;
Bits **fBitsHdl;
char fWork[TS_NAMEMAX];
LASCII wTitle;
/* コマンドライン上でファイル名が指定されたかどうか調べる */
fileexist = 0;
for (i = 1; i < pcv->argc; i++) {
if (strncmp(pcv->argv[i], "-w", 2) != 0) {
fileexist = 1;
break;
}
}
if (fileexist == 1) {
/* コマンドラインでファイル名が指定されていたなら */
/* 入力文字列をファイルネームにコピーする */
memcpy(fWork, pcv->argv[i], TS_NAMEMAX);
fWork[TS_NAMEMAX] = 0;
/* ファイル名が正常なら */
if (checkDrive(fWork, 2, 0)) {
strcpy(pcv->fileName, fWork);
/* ファイル名をタイトルに設定する */
wTitle[0] = sprintf((char *) &wTitle[1], "%s %s", WINTITLE, pcv->fileName);
/* タイトルの設定(ファイル名の更新) */
WMTitleSet(pcv->windowPtr, wTitle);
hFile = fopen(pcv->fileName, "rb");
if (hFile == NULL) {
fileexist = 0;
DMError(D_CONFIRM, "指定されたファイルが見付かりません。");
}
} else
fileexist = 0;
}
/* オフスクリーン用グラフとワーク用グラフをクリアする */
memset(&pcv->offGraph, 0, sizeof(Graph));
memset(&pcv->wkGraph, 0, sizeof(Graph));
/* ファイル名が指定されていたら */
if (fileexist == 1) {
/* ファイル読み込み用ワークのグラフをヌルクリアする */
memset(&fgraph, 0, sizeof(Graph));
/* ファイルを読み込む */
if (!readFile(pcv, hFile, &fBitsHdl)) {
if (fBitsHdl != NULL)
/* ワーク用のビッツハンドルを廃棄する */
GMDisposeBits(fBitsHdl);
fclose(hFile);
return FALSE;
}
fclose(hFile);
/* ビッツをロックする */
GMLockBits(fBitsHdl);
GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
/* ファイル読み込み用ワークグラフ情報を作成する */
fgraph.bmap = &(*fBitsHdl)->bmap;
if (GMCalcGraph(&fgraph) != 0)
return FALSE;
/* オフスクリーン用グラフ情報を作成する */
pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
if (GMCalcGraph(&pcv->offGraph) != 0)
return FALSE;
/* オフスクリーン用グラフをカレントグラフにする */
GMSetGraph(&pcv->offGraph);
/* ビットマップをセットする */
fgraph.bmap = &(*fBitsHdl)->bmap;
pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
/* ファイルグラフからオフスクリーン用グラフに転送する */
GMTransImg(&(*fBitsHdl)->bmap, &(*pcv->offBitsHdl[pcv->offIdx])->bmap, &pcv->pictSize, &pcv->pictSize);
/* ビッツをUnlockする */
GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
GMUnlockBits(fBitsHdl);
/* ファイルグラフのビットマップポインタだけヌルにして*/
fgraph.bmap = NULL;
/* ファイルグラフをクローズする */
GMCloseGraph(&fgraph);
/* ウィンドウサイズの更新 */
WMSize(pcv->windowPtr, pcv->nowWinSize.l.r_b, -1);
} else {
/* 絵のサイズを設定する */
pcv->pictSize.l.l_t = 0;
pcv->pictSize.d.right = pcv->windowPtr->graph.rect.d.right - pcv->windowPtr->graph.rect.d.left;
pcv->pictSize.d.bottom = pcv->windowPtr->graph.rect.d.bottom - pcv->windowPtr->graph.rect.d.top;
/* オフスクリーン用ビッツハンドルを確保する
(GR2モードにする)*/
pcv->offBitsHdl[pcv->offIdx] = GMNewBits(G_GR2, &pcv->pictSize, 0);
if (pcv->offBitsHdl[pcv->offIdx] == NULL)
return FALSE;
/* ビッツのビットイメージ領域をパレットNo.15でクリア */
memset((*pcv->offBitsHdl[pcv->offIdx])->data, 0xff, (size_t)(*pcv->offBitsHdl[pcv->offIdx])->size);
/* パレット値を初期化する */
for (i = 0; i < 16; i++) {
pcv->oldPaletBuf[i] = PaletOrg[i];
pcv->paletBuf[i] = PaletOrg[i];
}
/* オフスクリーン用グラフ情報を作成する */
pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
if (GMCalcGraph(&pcv->offGraph) != 0)
return FALSE;
}
/* オフスクリーン用グラフ作成完了フラグをオンにする */
pcv->offGraphOK = TRUE;
/* ワーク用ビッツハンドルを確保する */
pcv->wkBitsHdl = GMNewBits(G_TXT, &brrect, G_ALLPAGE);
if (pcv->wkBitsHdl == NULL)
return FALSE;
/* ビッツのビットイメージ領域をパレットNo.0でクリアする */
memset((*pcv->wkBitsHdl)->data, 0, (size_t)(*pcv->wkBitsHdl)->size);
/* ワーク用グラフ情報を作成する */
pcv->wkGraph.bmap = &(*pcv->wkBitsHdl)->bmap;
if (GMCalcGraph(&pcv->wkGraph) != 0)
return FALSE;
/* ワーク用グラフ作成完了フラグをオンにする */
pcv->wkGraphOK = TRUE;
/* パレットの設定をする */
setPalet(pcv->oldPaletBuf);
return TRUE;
}
/******************************************************************************
* preperaFInOut(): ファイル入出力用疑似ダイアログのための準備をする
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* 戻り値: BOOLEAN = TRUE: 作成成功
* = FALSE: 作成失敗
* 注釈:
* 疑似ダイアログで使用するコントロール、テキストエディットを作成します。
*/
BOOLEAN preperaFInOut(ComVal *pcv)
{
int errCode;
/* ファイル入出力用疑似ダイアログのデスティネーションレクタングル */
static Rect rcDest = { 28, 42, 316, 68 };
static short funcKeyTbl[] = { /* ファンクションキーアサインテーブル */
K_HOME, 0, /* [HOME] */
K_DEL, 0x07, /* [DEL] */
K_RUP, 0x03, /* [ROLL UP] */
K_RDOWN, 0x12, /* [ROLL DOWN] */
K_UNDO, 0, /* [UNDO] */
K_LEFT, 0x13, /* [←] */
K_UP, 0x05, /* [↑] */
K_RIGHT, 0x04, /* [→] */
K_DOWN, 0x18, /* [↓] */
K_CLR, 0, /* [CLR] */
K_HELP, 0, /* [HELP] */
K_INS, 0, /* [INS] */
0, 0 /* テーブル終端 */
};
/* [実行]ボタンを作成する */
pcv->eSetBtnHdl = CMOpen(pcv->windowPtr, &rcCbtnJ,
(_LASCII)"\x04実行", TRUE, 1, 0, 1, CI_CHRBTN << 4, 0);
if (pcv->eSetBtnHdl == NULL)
/* [実行]ボタンが作成できなかった */
return FALSE;
/* [取消]ボタンを作成する */
pcv->eCanBtnHdl = CMOpen(pcv->windowPtr, &rcCbtnT,
(_LASCII)"\x04取消", TRUE, 1, 0, 1, CI_CHRBTN << 4, 0);
if (pcv->eCanBtnHdl == NULL)
/* [取消]ボタンが作成できなかった */
return FALSE;
errCode = TMNew2(&rcDest, &rcView, &pcv->windowPtr->graph, &pcv->fTEditHdl);
if (errCode < 0)
return FALSE; /* テキストエディットが作成できなかった */
TMHide(pcv->fTEditHdl); /* テキストの表示モードをオフにする */
(*pcv->fTEditHdl)->lenMax = TS_NAMEMAX; /* 入力最大文字数をセット */
(*pcv->fTEditHdl)->lineHeight = T_LHEIGHT; /* 改行幅をセット */
/* 現在編集中のファイル名をセットする */
TMInsert(pcv->fTEditHdl, pcv->fileName, (int) strlen(pcv->fileName));
TMSetSelect(pcv->fTEditHdl, 0, (int) strlen(pcv->fileName), 0);
/* ファンクションキーアサインテーブルを設定する */
(*pcv->fTEditHdl)->funcCode = funcKeyTbl;
TMShow(pcv->fTEditHdl); /* テキストの表示モードをオンにする */
/* 拡大エリアの消去 */
dispLupeRect(pcv);
return TRUE;
}
/******************************************************************************
* createSizeSetCtrl(): 絵のサイズ設定疑似ダイアログ用コントロールの作成
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* 戻り値: BOOLEAN = TRUE: 作成成功
* = FALSE: 作成失敗
*/
BOOLEAN createSizeSetCtrl(ComVal *pcv)
{
char str[16];
static Rect rcGupdnX = { 40, 43, 120, 63 };
static Rect rcGupdnY = { 40, 66, 120, 86 };
static Rect rcGslvX = { 124, 45, 188, 61 };
static Rect rcGslvY = { 124, 68, 188, 84 };
/* [実行]ボタンを作成する */
pcv->eSetBtnHdl = CMOpen(pcv->windowPtr, &rcCbtnJ,
(_LASCII)"\x04設定", TRUE, 1, 0, 1, CI_CHRBTN << 4, 0);
if (pcv->eSetBtnHdl == NULL)
/* [実行]ボタンが作成できなかった */
return FALSE;
/* [取消]ボタンを作成する */
pcv->eCanBtnHdl = CMOpen(pcv->windowPtr, &rcCbtnT,
(_LASCII)"\x04取消", TRUE, 1, 0, 1, CI_CHRBTN << 4, 0);
if (pcv->eCanBtnHdl == NULL)
/* [取消]ボタンが作成できなかった */
return FALSE;
/* X の数値調整ボタン を作成する */
pcv->adjBtnHdl[0] = CMOpen(pcv->windowPtr, &rcGupdnX,
(_LASCII)"\x08 ", FALSE, 480, 1, 768, CI_ADJBTN << 4, 0);
if (pcv->adjBtnHdl[0] == NULL)
/* X の数値調整ボタンが作成できなかった */
return FALSE;
/* Y の数値調整ボタン を作成する */
pcv->adjBtnHdl[1] = CMOpen(pcv->windowPtr, &rcGupdnY,
(_LASCII)"\x08 ", FALSE, 256, 1, 512, CI_ADJBTN << 4, 0);
if (pcv->adjBtnHdl[1] == NULL)
/* X の数値調整ボタンが作成できなかった */
return FALSE;
/* X のスライドボリューム を作成する */
pcv->eSlvHdl[0] = CMOpen(pcv->windowPtr, &rcGslvX,
(_LASCII)"\x01 ", TRUE, 480, 1, 768, CI_SLDVOL << 4, 0);
if (pcv->eSlvHdl[0] == NULL)
/* X のスライドボリュームが作成できなかった */
return FALSE;
/* Y のスライドボリューム を作成する */
pcv->eSlvHdl[1] = CMOpen(pcv->windowPtr, &rcGslvY,
(_LASCII)"\x01 ", TRUE, 256, 1, 512, CI_SLDVOL << 4, 0);
if (pcv->eSlvHdl[1] == NULL)
/* Y のスライドボリュームが作成できなかった */
return FALSE;
pcv->ptPicXY.x_y = pcv->pictSize.l.r_b;
/* スライドボリューム Xのに値をセット */
CMValueSet(pcv->eSlvHdl[0], (int) pcv->ptPicXY.p.x);
/* スライドボリューム Yのに値をセット */
CMValueSet(pcv->eSlvHdl[1], (int) pcv->ptPicXY.p.y);
/* 数値調整ボタン X のタイトルを設定する */
sprintf(str, "\x04%4d", pcv->ptPicXY.p.x);
CMTitleSet(pcv->adjBtnHdl[0], (_LASCII) str);
CMValueSet(pcv->adjBtnHdl[0], (int) pcv->ptPicXY.p.x);
/* 数値調整ボタン Y のタイトルを設定する */
sprintf(str, "\x04%4d", pcv->ptPicXY.p.y);
CMTitleSet(pcv->adjBtnHdl[1], (_LASCII) str);
CMValueSet(pcv->adjBtnHdl[1], (int) pcv->ptPicXY.p.y);
/* 拡大エリアの消去 */
dispLupeRect(pcv);
/* サイズ設定ダイアログ表示中フラグセット */
pcv->sizeDlg = 1;
return TRUE;
}
/******************************************************************************
* checkSizeDlg(): 疑似サイズ設定ダイアログ内でのマウス左ダウン処理
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
*/
void checkSizeDlg(ComVal *pcv)
{
int lastFC, lastBC, lastPM, lastFM;
int partCode, cnum;
BOOLEAN flag;
Control **ctrlHdl; /* コントロールハンドル */
char str[16];
/* メインウィンドウをテキストタイプでカレントグラフにする */
setGraph(pcv->windowPtr, G_TXT);
GMAPage(G_PAGE0 | G_PAGE1); /* アクセスページを0と1ページにする */
lastPM = GMPenMode(G_PSET); /* ペンモードをPSETにする */
lastFC = GMForeColor(G_BLACK); /* フォアグラウンドカラーは黒 */
lastBC = GMBackColor(G_LGRAY); /* バックグラウンドカラーは白 */
lastFM = GMFontMode(G_PSET); /* フォントモードのセット */
/* マウスのボタンが押されている間、コントロールの各種処理をシステムに
任せて、コントロールハンドルとボタンが押された、または離された場所
のパートコードを取得する */
partCode = SXCallCtrlM(pcv->windowPtr, &pcv->event, 0, 0, NULL, &ctrlHdl);
switch (partCode) {
case C_INBTTN: /* 文字ボタンか? */
/* [設定]ボタンだったなら */
flag = (ctrlHdl == pcv->eSetBtnHdl);
/* 絵とウィンドウのサイズを変更する */
changePicSize(pcv, flag);
break;
case C_INDEC: /* 数値調整ボタン */
case C_ININC:
if (ctrlHdl == pcv->adjBtnHdl[0]) { /* X */
repeatAdjBtn(pcv, pcv->windowPtr, pcv->adjBtnHdl[0],
pcv->eSlvHdl[0], partCode, 4);
pcv->ptPicXY.p.x = CMValueGet(pcv->adjBtnHdl[0]);
} else if (ctrlHdl == pcv->adjBtnHdl[1]) { /* Y */
repeatAdjBtn(pcv, pcv->windowPtr, pcv->adjBtnHdl[1],
pcv->eSlvHdl[1], partCode, 4);
pcv->ptPicXY.p.y = CMValueGet(pcv->adjBtnHdl[1]);
}
break;
case C_INTHUMB: /* スライドボリューム */
if (ctrlHdl == pcv->eSlvHdl[0]) {
cnum = CMValueGet(pcv->eSlvHdl[0]);
pcv->ptPicXY.p.x = cnum;
/* 数値調整ボタンのタイトルを設定する */
sprintf(str, "\x04%4d", cnum);
CMTitleSet(pcv->adjBtnHdl[0], (_LASCII)str);
CMValueSet(pcv->adjBtnHdl[0], cnum);
} else if (ctrlHdl == pcv->eSlvHdl[1]) {
cnum = CMValueGet(pcv->eSlvHdl[1]);
pcv->ptPicXY.p.y = cnum;
/* 数値調整ボタンのタイトルを設定する */
sprintf(str, "\x04%4d", cnum);
CMTitleSet(pcv->adjBtnHdl[1], (_LASCII)str);
CMValueSet(pcv->adjBtnHdl[1], cnum);
}
break;
}
/* ペンモード、フォア/バックグラウンドカラー、フォントモードを元に戻す */
GMPenMode(lastPM);
GMForeColor(lastFC);
GMBackColor(lastBC);
GMFontMode(lastFM);
}
/******************************************************************************
* changePicSize(): 絵のサイズの変更実行処理
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* BOOLEAN execFlag 実行モード
* = 1: 実行
* = 0: 取消
*/
void changePicSize(ComVal *pcv, BOOLEAN execFlag)
{
int num;
int lastFC, lastBC;
unsigned short idx;
Rect rc, orc;
/* メインウィンドウをテキストタイプでカレントグラフにする */
setGraph(pcv->windowPtr, G_TXT);
lastFC = GMForeColor(G_LGRAY);
lastBC = GMBackColor(G_LGRAY);
num = 1;
/* 前の絵のレクタングルをセーブする */
orc = pcv->pictSize;
if (execFlag)
if (orc.d.right > pcv->ptPicXY.p.x || orc.d.bottom > pcv->ptPicXY.p.y)
num = DMError(D_YESNO, "絵の一部が失われます。\r"
"サイズの変更を行いますか?");
if (num == 1) {
/* 疑似ダイアログを消去するならば */
clearEseDlg(pcv);
/* サイズ設定ダイアログ表示中フラグセット */
pcv->sizeDlg = -1;
/* すべてのウィンドウのアップデートを行う */
allUpdate(pcv);
/* フォアグラウンドカラーを元に戻す */
GMForeColor(lastFC);
GMBackColor(lastBC);
if (execFlag) {
/* 設定された絵のサイズをセットする */
pcv->pictSize.l.r_b = pcv->ptPicXY.x_y;
pcv->nowWinSize = pcv->pictSize;
/* ウィンドウの最小レクタングルを設定する */
if (pcv->nowWinSize.d.right < 340)
pcv->nowWinSize.d.right = 340;
if (pcv->nowWinSize.d.bottom < 120)
pcv->nowWinSize.d.bottom = 120;
/* ウィンドウサイズの変更を行う*/
changeWinSize(pcv, &orc);
/* ウィンドウサイズの更新 */
WMSize(pcv->windowPtr, pcv->nowWinSize.l.r_b, 0);
/* 現在使用中のビッツハンドルではないほう */
/* のインデックスを取得する */
idx = (pcv->offIdx | 0xfffe) ^ 0xffff;
if (pcv->offBitsHdl[idx] != NULL)
/* UNDO用のビッツハンドルを廃棄する */
GMDisposeBits(pcv->offBitsHdl[idx]);
/* オフスクリーン用ビッツハンドルを確保する
(GR2モードにする)*/
pcv->offBitsHdl[idx] = GMNewBits(G_GR2, &pcv->pictSize, 0);
if (pcv->offBitsHdl[idx] == NULL) {
/* UNDO機能がONならば */
if (pcv->undoFlag) {
DMError(D_CONFIRM, "メモリが確保できません。\r"
"サイズ変更を中止し、\r"
"UNDOバッファを解放します。");
pcv->undoFlag = FALSE;
} else
DMError(D_CONFIRM, "メモリが確保できません。\r"
"サイズ変更を中止します。");
pcv->offBitsHdl[idx] = NULL;
goto nomemory;
}
/* 前の絵のレクタングルと設定されたレクタングルの小さい方を求める */
GMAndRect(&rc, &pcv->pictSize, &orc);
/* メインウィンドウをグラフィックタイプで
カレントグラフにする */
setGraph(pcv->windowPtr, G_GRP);
/* ビッツをロックする */
GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
GMLockBits(pcv->offBitsHdl[idx]);
/* ビッツのビットイメージ領域をパレットNo.15でクリア */
memset((*pcv->offBitsHdl[idx])->data, 0xff, (size_t)(*pcv->offBitsHdl[idx])->size);
/* オフスクリーン用グラフ情報を作成する */
pcv->offGraph.bmap = &(*pcv->offBitsHdl[idx])->bmap;
GMCalcGraph(&pcv->offGraph);
/*pcv->offGraph.bmap = &(*pcv->offBitsHdl[idx])->bmap;*/
/* 現在使用中のバッファからUNDO用のバッファにコピー */
GMCopy(&(*pcv->offBitsHdl[pcv->offIdx])->bmap, &(*pcv->offBitsHdl[idx])->bmap, &rc, &rc, G_PSET, NULL);
GMUnlockBits(pcv->offBitsHdl[idx]);
GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
/* 現在編集中バッファ用のビッツハンドルを廃棄する */
GMDisposeBits(pcv->offBitsHdl[pcv->offIdx]);
pcv->offBitsHdl[pcv->offIdx] = NULL;
/* UNDO機能がONならば */
if (pcv->undoFlag) {
/* UNDO用ビッツハンドルを確保する
(GR2モードにする)*/
pcv->offBitsHdl[pcv->offIdx] = GMNewBits(G_GR2, &pcv->pictSize, 0);
if (pcv->offBitsHdl[pcv->offIdx] == NULL) {
DMError(D_CONFIRM, "UNDOのためのメモリが確保できません。\r"
"UNDO機能の使用を中止します。");
/* ビッツインデックスを入れ換える */
pcv->offIdx = idx;
/* メニューのUNDO On/Off の状態を変更する */
pcv->undoFlag = FALSE;
goto nomemory;
}
/* ビッツをロックする */
GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
GMLockBits(pcv->offBitsHdl[idx]);
/* 絵のデータをUNDO用のバッファにコピー */
GMCopy(&(*pcv->offBitsHdl[idx])->bmap, &(*pcv->offBitsHdl[pcv->offIdx])->bmap, &pcv->pictSize, &pcv->pictSize, G_PSET, NULL);
GMUnlockBits(pcv->offBitsHdl[idx]);
GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
}
/* ビッツインデックスを入れ換える */
pcv->offIdx = idx;
/* ウィンドウサイズの変更を行う*/
changeWinSize(pcv, &orc);
/* ウィンドウサイズの更新 */
WMSize(pcv->windowPtr, pcv->nowWinSize.l.r_b, 0);
/* 絵全体のレクタングル部分をオフスクリーンからコピー
する */
addUpdate(pcv->windowPtr, NULL);
}
nomemory:
/* サイズ設定ダイアログ表示中フラグをクリア */
pcv->sizeDlg = 0;
/* メニューを使用可にする */
/* メインウィンドウをカレントグラフにする */
GMSetGraph(&pcv->windowPtr->graph);
}
}
/******************************************************************************
* clearEseDlg(): 疑似ダイアログを消去する
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
*/
void clearEseDlg(ComVal *pcv)
{
int stat;
int lastPM;
Region **rgnHdl;
CMKill(pcv->windowPtr);
/* 疑似ダイアログ全体をクリア */
GMFillRect(&rcFdlg);
/* 使用するリージョンハンドルを取得する */
rgnHdl = GMNewRgn();
if (rgnHdl == NULL) {
DMError(D_CONFIRM, "メモリが確保できません。");
return;
}
lastPM = GMPenMode(G_PSET);
GMForeColor(G_THRU); /* フォアグラウンドカラーは透明色 */
/* 疑似ダイアログのレクタングルをリージョンに求める */
GMRectRgn(rgnHdl, &rcFdlg);
/* 絵の外側で疑似ダイアログの内側の部分を求める */
GMAndRectRgn(rgnHdl, rgnHdl, &pcv->pictSize);
stat = GMEmptyRgn(rgnHdl);
if (stat == 0)
/* ヌルリージョンでなければ、疑似ダイアログのレクタングルを透明色で塗りつぶす */
GMFillRgn(rgnHdl);
/* ペンモード、フォアグラウンドカラーを元に戻す */
GMPenMode(lastPM);
GMDisposeRgn(rgnHdl); /* リージョンハンドルを解放する */
}
/******************************************************************************
* makeRect(): 2点よりレクタングルデータを作成する
******************************************************************************
* 引数: LPoint lpt1 第1点目の点
* LPoint lpt2 第2点目の点
* Rect *prc 描画範囲のレクタングルへのポインタ
* Rect *pcrc 2点より作成されるレクタングルへのポインタ
*/
void makeRect(LPoint lpt1, LPoint lpt2, Rect *prc, Rect *pcrc)
{
Point pt1, pt2;
Point penSize[2] = {{ 0, 0 }, { 0, 0 }};
pt1.x_y = lpt1;
pt2.x_y = lpt2;
/* 第2点の座標 pt2 がウィンドウをはずれていれば調節する */
ajustPoint(&pt2, penSize, prc);
/* pt1 と pt2 のX座標を比較して小さい方を pt1.p.x 大きい方を pt2.p.x にセットする */
pcrc->d.left = min(pt1.p.x, pt2.p.x);
pcrc->d.right = max(pt1.p.x, pt2.p.x);
/* pt1 と pt2 のY座標を比較して小さい方を pt1.p.y 大きい方を pt2.p.y にセットする */
pcrc->d.top = min(pt1.p.y, pt2.p.y);
pcrc->d.bottom = max(pt1.p.y, pt2.p.y);
}
/******************************************************************************
* ajustPoint(): 点がレクタングル領域外れていたらレクタングル内にする
******************************************************************************
* 引数: Point *pt 調節する点へのポインタ
* Point *psize ペンサイズの配列へのポインタ
* Rect *prc 描画範囲のレクタングルへのポインタ
* 注釈:
* ペンサイズの値に0以外の値が設定されている場合は、ウィンドウの最大値は
* ペンサイズの値を引いたサイズとして考える。
*/
void ajustPoint(Point *pt, Point *psize, Rect *prc)
{
Point w_max, w_min;
/* ウィンドウの最大座標をセットする */
w_max.x_y = prc->l.r_b;
/* ウィンドウの最小座標をセットする */
w_min.x_y = prc->l.l_t;
/* ペンサイズがセットされていれば最大値はペンサイスを引いた値 */
if (psize[0].x_y != 0) {
w_max.p.x -= psize[0].p.x;
w_max.p.y -= psize[0].p.y;
}
/* ペンサイズがセットされていれば最小値はペンサイスを足した値 */
if (psize[1].x_y != 0) {
w_min.p.x += psize[1].p.x;
w_min.p.y += psize[1].p.y;
}
/* 点がウィンドウをはずれていれば調節する */
if (pt->p.x < w_min.p.x)
pt->p.x = w_min.p.x;
else if (pt->p.x > w_max.p.x)
pt->p.x = w_max.p.x;
if (pt->p.y < w_min.p.y)
pt->p.y = w_min.p.y;
else if (pt->p.y > w_max.p.y)
pt->p.y = w_max.p.y;
}
/******************************************************************************
* ajustEndPoint(): 点がレクタングル領域外れていたらレクタングル内にする
******************************************************************************
* 引数: LPoint lptb 直線の始点
* Point *ppte 直線の終点(調整された直線の終点が格納される)
* Rect *prc 指定されるレクタングル
*/
void ajustEndPoint(LPoint lptb, Point *ppte, Rect *prc)
{
int flag = 0;
double a, b;
Point ptb;
ptb.x_y = lptb;
/* 直線の方程式 y = ax + b の a および b を求める */
/* X軸に平行な直線かY軸に平行な直線か判断する */
if (ptb.p.x == ppte->p.x)
flag = 1; /* Y軸に平行な直線 : 例 : X = 5; */
if (ptb.p.y == ppte->p.y) {
if (flag == 1)
/* 同一点であるから何もしない */
return;
flag = 2; /* X軸に平行な直線 : 例 : Y = 5; */
}
switch (flag) {
case 0: /* X軸とY軸に平行でない直線のときは */
/* 直線の方程式 y = ax + b の a および b を求める */
a = (double)(ppte->p.y - ptb.p.y) / (double)(ppte->p.x - ptb.p.x);
b = (double) ptb.p.y - a * (double) ptb.p.x;
if (ppte->p.x < prc->d.left) {
/* X座標がウィンドウの左ならX、Y座標をそれぞれ調節する */
ppte->p.x = prc->d.left;
ppte->p.y = (short)(a * (double) prc->d.left + b);
} else if (ppte->p.x > prc->d.right) {
/* X座標がウィンドウの右ならX、Y座標をそれぞれ調節する */
ppte->p.x = prc->d.right;
ppte->p.y = (short)(a * (double) prc->d.right + b);
}
if (ppte->p.y < prc->d.top) {
/* Y座標がウィンドウの上だったならX、Y座標をそれぞれ調節する */
ppte->p.x = (short)(((double) prc->d.top - b) / a);
ppte->p.y = prc->d.top;
} else if (ppte->p.y > prc->d.bottom) {
/* Y座標がウィンドウの下だったならX、Y座標をそれぞれ調節する */
ppte->p.x = (short)(((double) prc->d.bottom - b) / a);
ppte->p.y = prc->d.bottom;
}
break;
case 1: /* Y軸に平行な直線のとき */
if (ppte->p.y < prc->d.top)
/* Y座標がウィンドウの上だったならY座標をtopの座標にする */
ppte->p.y = prc->d.top;
else if (ppte->p.y > prc->d.bottom)
/* Y座標がウィンドウの下だったならY座標をbottomの座標にする */
ppte->p.y = prc->d.bottom;
break;
case 2: /* X軸に平行な直線のとき */
if (ppte->p.x < prc->d.left)
/* X座標がウィンドウの左だったならX座標をleftの座標にする */
ppte->p.x = prc->d.left;
else if (ppte->p.x > prc->d.right)
/* X座標がウィンドウの右だったならX座標をrightの座標にする */
ppte->p.x = prc->d.right;
break;
}
}
/******************************************************************************
* setFBColor(): カレントグラフのフォア/バックグラウンドカラーのセット
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* 注釈:
* ペンパターンの使用の有無をみてフォア/バックグラウンドカラーをセットする
*/
void setFBColor(ComVal *pcv)
{
BitImg *wPtr;
if (!pcv->ptrnUse) {
/* ペンパターンは使用しないとき */
/* 選択中のパレット番号セット*/
OldFC = GMForeColor(pcv->paletNo);
/* バックグラウンドカラーは白 */
OldBC = GMBackColor(15);
/* 描画モードをP_SETモードにする */
OldPM = GMPenMode(G_PSET);
} else {
/* ペンパターンの使用が選択されているとき */
/* ペンパターンの初期値のアドレスを取得する */
wPtr = (*pcv->tileImg[pcv->ptrnNo])->data + 16;
/* ペンパターンをセットする */
GMPenPat(wPtr);
/* 選択中のフォアグラウンドカラー番号セット */
OldFC = GMForeColor(pcv->ptrnColor[0]);
/* 選択中のバックグラウンドカラー番号セット */
OldBC = GMBackColor(pcv->ptrnColor[1]);
/* 描画モードをペンパターンモードにする */
OldPM = GMPenMode(G_PPAT << 8); /* ペンパターンの使用 */
}
}
/******************************************************************************
* changeWinSize(): ウィンドウのサイズを変更する
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* Rect *prc 現在のウィンドウサイズへのポインタ
*/
void changeWinSize(ComVal *pcv, Rect *prc)
{
int lastFC, lastPM;
short work;
Rect rc;
/* ルーペのレクタングルを調節する */
work = 100 - (LOWWORD(pcv->toolStat[4]) * 50);
if (pcv->rcLupe.d.right > pcv->pictSize.d.right) {
pcv->rcLupe.d.left = pcv->pictSize.d.right - work;
pcv->rcLupe.d.right = pcv->pictSize.d.right;
}
if (pcv->rcLupe.d.bottom > pcv->pictSize.d.bottom) {
pcv->rcLupe.d.top = pcv->pictSize.d.bottom - work;
pcv->rcLupe.d.bottom = pcv->pictSize.d.bottom;
}
if (pcv->rcLupe.d.left < 0) {
pcv->rcLupe.d.left = 0;
pcv->rcLupe.d.right = work;
}
if (pcv->rcLupe.d.top < 0) {
pcv->rcLupe.d.top = 0;
pcv->rcLupe.d.bottom = work;
}
/* メインウィンドウをテキストタイプでカレントグラフにする */
setGraph(pcv->windowPtr, G_TXT);
lastPM = GMPenMode(G_PSET);
lastFC = GMForeColor(G_THRU); /* フォアグラウンドカラーは透明色 */
if (prc->d.right < pcv->pictSize.d.right && prc->d.right < 340) {
/* 新しいXサイズの方が大きくて前の絵のサイズが340より小さいとき */
rc = pcv->pictSize;
rc.d.left = prc->d.right;
if (rc.d.right > 340)
rc.d.right = 340;
/* 透明色でウィンドウの一部を塗りつぶす */
GMFillRect(&rc);
} else if (prc->d.right > pcv->pictSize.d.right && pcv->pictSize.d.right < 340) {
/* 前のXサイズの方が大きくて新しい絵のサイズが340より小さいとき */
rc = *prc;
rc.d.left = pcv->pictSize.d.right;
if (rc.d.right > 340)
rc.d.right = 340;
GMForeColor(G_LGRAY); /* フォアグラウンドカラーはライトグレー */
/* ライトグレーでウィンドウの一部を塗りつぶす */
GMFillRect(&rc);
}
if (prc->d.bottom < pcv->pictSize.d.bottom && prc->d.bottom < 120) {
/* 新しいYサイズの方が大きくて前の絵のサイズが120より小さいとき */
rc = pcv->pictSize;
rc.d.top = prc->d.bottom;
if (rc.d.bottom > 120)
rc.d.bottom = 120;
/* 透明色でウィンドウの一部を塗りつぶす */
GMFillRect(&rc);
} else if (prc->d.bottom > pcv->pictSize.d.bottom && pcv->pictSize.d.bottom < 120) {
/* 前のYサイズの方が大きくて新しい絵のサイズが120より小さいとき */
rc = *prc;
rc.d.top = pcv->pictSize.d.bottom;
if (rc.d.bottom > 120)
rc.d.bottom = 120;
GMForeColor(G_LGRAY); /* フォアグラウンドカラーはライトグレー */
/* ライトグレーでウィンドウの一部を塗りつぶす */
GMFillRect(&rc);
}
/* ペンモード、フォアグラウンドカラーを元に戻す */
GMPenMode(lastPM);
GMForeColor(lastFC);
}
/******************************************************************************
* allUpdate(): サブウィンドウを含むすべてのアップデードリージョンの
部分を描き直す
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
*/
void allUpdate(ComVal *pcv)
{
int i;
/* サブウィンドウのアップデート */
for (i = 0; i < SUBMAX; i++)
if (pcv->subwinPtr[i] != NULL)
addUpdate(&pcv->subwinPtr[i]->win, NULL);
addUpdate(pcv->windowPtr, NULL);
}
/******************************************************************************
* plusRectImg(): 2つのレクタングルイメージを重ねて表示
******************************************************************************
* 引数: RectImg **phdl レクタングルイメージのハンドル
* RectImg **cimg 作成するビットイメージのハンドル
* LPoint oflp cpImageを重ねるオフセット座標
* LPoint lpt 表示座標
* int flag 表示モード
*/
void plusRectImg(RectImg **phdl, RectImg **cimg, LPoint oflp, LPoint lpt, int flag)
{
int i;
Rect drc, src, mrc;
RectImg *drp, *mrp;
Bitmap sbm, dbm, mbm;
short dimg[4 + 160], mimg[4 + 40];
drp = (RectImg *) &dimg[0];
mrp = (RectImg *) &mimg[0];
memcpy(&drp->data, &(*phdl)->data, 4 * 20 * 4);
drc = drp->bounds = (*phdl)->bounds;
/* cimgが0の場合phdlだけ表示 */
if (cimg) {
/* マスク用ビットイメージを作成 */
mrp->bounds = (*cimg)->bounds;
src = mrc = mrp->bounds;
for (i = 4; i < 44; i++)
mimg[i] = 0xffff;
MMHdlLock(cimg);
makeBitmap(drp, &dbm, 0, 3); /* コピー用 Bitmap を作成 */
makeBitmap(mrp, &mbm, 0, 1); /* マスク用 Bitmap を作成 */
makeBitmap(*cimg, &sbm, 0, 3); /* コピー用 Bitmap を作成 */
/* ビットイメージを重ねる */
GMCopyMask(&sbm, &dbm, &mbm, &src, oflp, &mrc);
MMHdlUnlock(cimg);
}
GMSlideRect(&drc, lpt);
/* 重ねたイメージを表示 */
GMPlotImg(drp->data, &drc, flag);
}
/******************************************************************************
* makeBitmap(): RectImgよりビットマップを作成
******************************************************************************
* 引数: RectImg *img レクタングルイメージポインタ
* Bitmap *pbitmap 作成するビットマップポインタ
* int ofp 開始プレーン番号
* short ap アクセスページ
*/
void makeBitmap(RectImg *img, Bitmap *pbitmap, int ofp, short ap)
{
int x, y, lineb, screenb;
x = img->bounds.d.right;
y = img->bounds.d.bottom;
lineb = (x / 16 + (((x % 16) == 0 ) ? 0 : 1)) * 2; /* 1ラインあたりのバイト数 */
screenb = y * lineb; /* 1プレーンのバイト数 */
pbitmap->type = G_TXT; /* text type */
pbitmap->rect = img->bounds; /* レクタングル */
pbitmap->base = (char *) img->data + screenb * ofp; /* ベースアドレス */
pbitmap->line = lineb; /* 横1ラインのアドレス */
pbitmap->opt.tbm.page = screenb; /* 1ページのバイト数 */
pbitmap->opt.tbm.aPage = ap; /* アクセスページ */
}
/******************************************************************************
* changeUndo(): アンドゥーのON/OFFの状態を変更する
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
*/
void changeUndo(ComVal *pcv)
{
unsigned short idx;
/* 現在使用中のビッツハンドルではないほうのインデックスを取得する */
idx = (pcv->offIdx | 0xfffe) ^ 0xffff;
if (!pcv->undoFlag) { /* UNDOは現在OFFなら */
/* UNDO用ビッツハンドルを確保する(GR2モードにする)*/
pcv->offBitsHdl[idx] = GMNewBits(G_GR2, &pcv->pictSize, 0);
if (pcv->offBitsHdl[idx] == NULL) {
DMError(D_CONFIRM, "UNDOのためのメモリが確保できません。");
return;
}
pcv->undoFlag = TRUE; /* UNDOをONに */
GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
GMLockBits(pcv->offBitsHdl[idx]);
/* UNDOバッファの方にも同じ内容を書き込む */
GMCopy(&(*pcv->offBitsHdl[pcv->offIdx])->bmap, &(*pcv->offBitsHdl[idx])->bmap, &pcv->pictSize, &pcv->pictSize, G_PSET, NULL);
GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
GMUnlockBits(pcv->offBitsHdl[idx]);
} else { /* UNDOは現在ONなら */
pcv->undoFlag = FALSE; /* UNDOをOFFに */
if (pcv->offBitsHdl[idx] != NULL) {
/* UNDO用のビッツハンドルを廃棄する */
GMDisposeBits(pcv->offBitsHdl[idx]);
pcv->offBitsHdl[idx] = NULL;
}
}
}